﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using CjcPhotoPrint.Exporters;
using Microsoft.Win32;

namespace CjcPhotoPrint
{
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
		public static DependencyProperty ImagesProperty = DependencyProperty.Register(
			"Images",
			typeof( ObservableCollection<Transformable> ),
			typeof( MainWindow ) );

		public static RoutedCommand About = new RoutedCommand( "About", typeof( MainWindow ) );

		public enum FileType
		{
			Video,
			Image,
			NotSupported
		}

		public MainWindow()
		{
			InitializeComponent();
			Images = new ObservableCollection<Transformable>();
		}

		public ObservableCollection<Transformable> Images
		{
			get { return (ObservableCollection<Transformable>)GetValue( ImagesProperty ); }
			set { SetValue( ImagesProperty, value ); }
		}

		public bool ItemSelected
		{
			get { return CollectionViewSource.GetDefaultView( Images ).CurrentItem != null; }
		}

		private void crop_Click( object sender, RoutedEventArgs e )
		{
			SelectTransformation( SelectedTransformationContext.AddCrop() );
		}

		private void straighten_Click( object sender, RoutedEventArgs e )
		{
			SelectTransformation( SelectedTransformationContext.AddStraighten() );
		}

		private void rotate_Click( object sender, RoutedEventArgs e )
		{
			SelectTransformation( SelectedTransformationContext.AddRotate() );
		}

		private TransformationContext SelectedTransformationContext
		{
			get
			{
				var source = imageSelect.SelectedItem as Transformable;
				var transformations = CollectionViewSource.GetDefaultView( source.Transformations );
				return transformations.CurrentItem as TransformationContext;
			}
		}

		private TransformationContext SelectTransformation( TransformationContext context )
		{
			var source = imageSelect.SelectedItem as Transformable;
			var transformations = CollectionViewSource.GetDefaultView( source.Transformations );
			transformations.MoveCurrentTo( context );

			return context;
		}

		private void delete_Click( object sender, RoutedEventArgs e )
		{
			var button = sender as Button;
			var transformation = button.DataContext as TransformationContext;

			var transformations = CollectionViewSource.GetDefaultView( transformation.Source.Transformations );

			if ( transformations.CurrentItem == transformation ) transformations.MoveCurrentToNext();

			transformation.Source.RemoveTransformation( transformation );
		}

		private void printDirect_Click( object sender, RoutedEventArgs e )
		{
			new Print().Export( new[] { imageSelect.SelectedItem as Transformable }, Dispatcher );
		}

		private void printWizard_Click( object sender, RoutedEventArgs e )
		{

		}

		private void save_Click( object sender, RoutedEventArgs e )
		{
			new Save().Export( new[] { imageSelect.SelectedItem as Transformable }, Dispatcher );
		}

		private void Open_Executed( object sender, ExecutedRoutedEventArgs e )
		{
			var dialog = new OpenFileDialog
			{
				CheckFileExists = true,
				Title = "Open Photo",
				Filter = "Image Files (*.jpg; *.png; *.bmp; *.gif)|*.jpg; *.png; *.bmp; *.gif",
				Multiselect = true,
				InitialDirectory = Environment.GetFolderPath( Environment.SpecialFolder.MyPictures )
			};

			if ( dialog.ShowDialog() ?? false ) AddImages( dialog.FileNames );
		}

		public void AddImages( IEnumerable<string> filenames )
		{
			bool first = true;

			foreach ( var filename in filenames )
			{
				Images.Add( new TransformableImage( filename ) );

				if ( first )
				{
					CollectionViewSource.GetDefaultView( Images ).MoveCurrentToLast();
					first = false;
				}
			}
		}

		private void SaveAs_Executed( object sender, ExecutedRoutedEventArgs e )
		{
			new Save().Export( imageSelect.Items.Cast<Transformable>().Where( t => t.Selected ), Dispatcher );
		}

		private void Print_Executed( object sender, ExecutedRoutedEventArgs e )
		{
			printDirect_Click( sender, e );
		}

		private void Close_Executed( object sender, ExecutedRoutedEventArgs e )
		{
			Close();
		}

		private void About_Executed( object sender, ExecutedRoutedEventArgs e )
		{
			new About { Owner = this }.ShowDialog();
		}

		private void Window_Drop( object sender, DragEventArgs e )
		{
			AddImages( e.Data.GetData( DataFormats.FileDrop, true ) as string[] );

			e.Handled = true;
		}

		private void Window_DragOver( object sender, DragEventArgs e )
		{
			e.Effects = DragDropEffects.None;

			var fileNames = e.Data.GetData( DataFormats.FileDrop, true ) as string[];

			foreach ( string fileName in fileNames )
			{
				var type = GetFileType( fileName );

				// Only Image files are supported
				if ( type == FileType.Image )
					e.Effects = DragDropEffects.Copy;
			}

			// Mark the event as handled, so control's native DragOver handler is not called.
			e.Handled = true;
		}

		/// <summary>Returns the FileType </summary>
		/// <param name="fileName">Path of a file.</param>
		public FileType GetFileType( string fileName )
		{
			string extension = System.IO.Path.GetExtension( fileName ).ToLower();

			if ( new[] { ".jpg", ".png", ".gif", "bmp" }.Contains( extension ) )
				return FileType.Image;

			// TODO
			if ( extension == ".wmv" )
				return FileType.Video;

			return FileType.NotSupported;
		}
	}
}